package net.jgrm.product.dubbo.impl;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import net.jgrm.product.dto.ProductDTO;
import net.jgrm.product.dubbo.ProductDubboService;
import net.jgrm.product.entity.Product;
import net.jgrm.product.service.IProductService;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 商品Dubbo服务实现类
 */
@DubboService(version = "1.0.0", loadbalance = "random")
public class ProductDubboServiceImpl implements ProductDubboService {

    @Autowired
    private IProductService productService;

    @Override
    @SentinelResource(value = "dubbo_getProductById", blockHandler = "getProductByIdBlockHandler")
    public ProductDTO getProductById(Long id) {
        Product product = productService.getProductById(id);
        return convertToDTO(product);
    }

    @Override
    @SentinelResource(value = "dubbo_decreaseStock", blockHandler = "decreaseStockBlockHandler")
    public boolean decreaseStock(Long productId, Integer quantity) {
        return productService.decreaseStock(productId, quantity);
    }

    @Override
    @SentinelResource(value = "dubbo_getProductsByIds", blockHandler = "getProductsByIdsBlockHandler")
    public List<ProductDTO> getProductsByIds(List<Long> productIds) {
        if (CollectionUtils.isEmpty(productIds)) {
            return new ArrayList<>();
        }
        // 实现批量查询逻辑（需要在IProductService中添加相应方法）
        return productIds.stream()
                .map(id -> {
                    try {
                        Product product = productService.getProductById(id);
                        return convertToDTO(product);
                    } catch (Exception e) {
                        return null;
                    }
                })
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
    }

    @Override
    @SentinelResource(value = "dubbo_checkStock", blockHandler = "checkStockBlockHandler")
    public boolean checkStock(Long productId, Integer quantity) {
        try {
            Product product = productService.getProductById(productId);
            return product != null && product.getStock() != null && product.getStock() >= quantity;
        } catch (Exception e) {
            return false;
        }
    }

    @Override
    @SentinelResource(value = "dubbo_getCurrentStock", blockHandler = "getCurrentStockBlockHandler")
    public Integer getCurrentStock(Long productId) {
        try {
            Product product = productService.getProductById(productId);
            return product != null ? product.getStock() : 0;
        } catch (Exception e) {
            return 0;
        }
    }

    @Override
    @SentinelResource(value = "dubbo_batchCheckStock", blockHandler = "batchCheckStockBlockHandler")
    public Map<Long, Boolean> batchCheckStock(Map<Long, Integer> stockCheckMap) {
        if (CollectionUtils.isEmpty(stockCheckMap)) {
            return new HashMap<>();
        }

        Map<Long, Boolean> resultMap = new HashMap<>();
        for (Map.Entry<Long, Integer> entry : stockCheckMap.entrySet()) {
            Long productId = entry.getKey();
            Integer quantity = entry.getValue();
            resultMap.put(productId, checkStock(productId, quantity));
        }
        return resultMap;
    }

    // 限流/熔断处理 - 查询商品
    public ProductDTO getProductByIdBlockHandler(Long id, BlockException e) {
        e.printStackTrace();
        return new ProductDTO(); // 返回空对象或默认商品
    }

    // 限流/熔断处理 - 扣减库存
    public boolean decreaseStockBlockHandler(Long productId, Integer quantity, BlockException e) {
        e.printStackTrace();
        return false; // 限流时返回扣减失败
    }

    // 限流/熔断处理 - 批量查询商品
    public List<ProductDTO> getProductsByIdsBlockHandler(List<Long> productIds, BlockException e) {
        e.printStackTrace();
        return new ArrayList<>();
    }

    // 限流/熔断处理 - 检查库存
    public boolean checkStockBlockHandler(Long productId, Integer quantity, BlockException e) {
        e.printStackTrace();
        return false;
    }

    // 限流/熔断处理 - 获取当前库存
    public Integer getCurrentStockBlockHandler(Long productId, BlockException e) {
        e.printStackTrace();
        return 0;
    }

    // 限流/熔断处理 - 批量检查库存
    public Map<Long, Boolean> batchCheckStockBlockHandler(Map<Long, Integer> stockCheckMap, BlockException e) {
        e.printStackTrace();
        return new HashMap<>();
    }

    /**
     * 将Product实体转换为ProductDTO
     */
    private ProductDTO convertToDTO(Product product) {
        if (product == null) {
            return null;
        }
        ProductDTO dto = new ProductDTO();
        BeanUtils.copyProperties(product, dto);
        return dto;
    }
}
